package com.m7.practice1;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author: shaochong
 * @Date: 2021/1/8
 * @Description:
 */



public class TestStream {

    private static List<Person> personList = new ArrayList<Person>();

    static {
        personList.add(new Person("欧阳雪",18,"中国",'F'));
        personList.add(new Person("Tom",24,"美国",'M'));
        personList.add(new Person("Harley",22,"英国",'F'));
        personList.add(new Person("向天笑",20,"中国",'M'));
        personList.add(new Person("李康",22,"中国",'M'));
        personList.add(new Person("小梅",20,"中国",'F'));
        personList.add(new Person("何雪",21,"中国",'F'));
        personList.add(new Person("李康",22,"中国",'M'));
    }

    public static void main(String[] args) {
        System.out.println(personList.size());
        test7();
    }

    public static void test1() {
        // 1.找到年龄>18的并输出
        personList.stream().filter((p) -> p.getAge() > 18).forEach(System.out::println);
        // 2.找出所有中国人的数量
        long count = personList.stream().filter(person -> person.getCountry().equals("中国")).count();
        System.out.println("中国人数量:" + count);
    }

    public static void test2() {
        // 3. 取出两个女性并打印 limit
        personList.stream()
                .filter(person -> person.getSex() == 'F')
                .limit(2)
                .forEach(System.out::println);
        // 4. 从第二个女性开始,取出所有女性
        personList.stream()
                .filter(person -> person.getSex() == 'F')
                .skip(1)
                .forEach(System.out::println);
        // 5. distinct 去重
        personList.stream().filter(person -> person.getSex() == 'M')
                .distinct()
                .forEach(System.out::println);
    }

    /**
     * map--接收Lambda，将元素转换成其他形式或提取信息。接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。
     * flatMap--接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流
     */
    public static void test3() {
        @Data
        class PersonCountry {
            private String country;
        }
        personList.stream().map(person -> {
            PersonCountry personName = new PersonCountry();
            personName.setCountry(person.getCountry());
            return personName;
        }).distinct().forEach(System.out::println);
    }

    /**
     * 排序
     */
    public static void test4() {
        personList.stream().sorted((p1, p2) -> {
            if (p1.getAge().equals(p2.getAge())) {
                return p1.getName().compareTo(p2.getName());
            } else {
                return p1.getAge().compareTo(p2.getAge());
            }
        }).forEach(System.out::println);
    }

    /**
     * 查找与匹配
     * allMatch--检查是否匹配所有元素
     * anyMatch--检查是否至少匹配一个元素
     * noneMatch--检查是否没有匹配所有元素
     * findFirst--返回第一个元素
     * findAny--返回当前流中的任意元素
     * count--返回流中元素的总个数
     * max--返回流中最大值
     * min--返回流中最小值
     */

    public static void test5() {
        boolean b1 = personList.stream().allMatch(p -> p.getAge() >= 18);
        System.out.println("是否都是成年人:" + b1);
        // 是否都是中国人
        boolean b2 = personList.stream().allMatch(person -> person.getCountry().equals("中国"));
        // 年龄最大人的信息
        Optional<Person> p = personList.stream().max((p1, p2) ->  p1.getAge().compareTo(p2.getAge() ) );
        System.out.println("person:" + p.get());
        // 年龄最小信息
        Optional<Person> minP = personList.stream().min((p1, p2) -> p1.getAge().compareTo(p2.getAge()));
        System.out.println("person:" + minP.get());
    }

    /**
     * 归约 reduce
     */
    public static void test6() {
        List<Integer> integerList = new ArrayList<>(100);
        for(int i = 1; i<= 100; i++) {
            integerList.add(i);
        }
        final Integer sum = integerList.stream().reduce(0, (x, y) -> x + y);
        System.out.println("结果:" + sum);
    }

    /**
     * 收集 collect：将流转换为其他形式，接收一个Collector接口实现 ，用于给Stream中汇总的方法
     */
    public static void test7() {
        // 将国家收集起来转换为list
        List<String> collect = personList.stream().map(Person::getCountry).distinct().collect(Collectors.toList());
        System.out.println("collect: " + collect);
        // 计算出平均年龄
        final Double collect1 = personList.stream().collect(Collectors.averagingInt(p -> p.getAge()));
        System.out.println("平均年龄:" + collect1);
        // 找到最大最小年龄
        final Optional<Integer> maxAge = personList.stream().map(Person::getAge).collect(Collectors.maxBy(Integer::compareTo));
        System.out.println("最大年龄:" + maxAge);
    }
}
